package com.cci.kangdao.service.impl;

import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.cci.kangdao.common.RedisKeys;
import com.cci.kangdao.dao.NotifyRecordTDao;
import com.cci.kangdao.dao.RelationShipTDao;
import com.cci.kangdao.dao.UserTDao;
import com.cci.kangdao.dao.model.NotifyRecord;
import com.cci.kangdao.dao.model.RelationShipT;
import com.cci.kangdao.utilTool.*;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.ModelAndView;

import com.cci.kangdao.dao.LoginDao;
import com.cci.kangdao.dao.model.UserT;
import com.cci.kangdao.redis.RedisClientUtils;
import com.cci.kangdao.service.NoticeService;
import com.cci.kangdao.service.PropertiesUtils;

@Service("noticeService")
public class NoticeServiceImpl implements NoticeService {

    @Autowired
    private RedisClientUtils redisClientUtils;
    @Autowired
    private LoginDao loginDao;
    @Autowired
    private PropertiesUtils propertiesUtils;
    @Resource
    private NotifyRecordTDao notifyRecordTDao;
    @Resource
    private RelationShipTDao relationShipTDao;
    @Resource
    private UserTDao userTDao;

    private final static Logger log = Logger.getLogger(NoticeServiceImpl.class);

    private static final String GETUI_KEY = "getui";

    @Override
    public ModelAndView bindClientId(Map<String, Object> map) {
        try {
            HttpServletResponse response = (HttpServletResponse) map.get("response");
            HttpServletRequest request = (HttpServletRequest) map.get("request");
            JSONObject obj = new JSONObject();
            if (StringUtils.isEmpty((String) map.get("cId"))) {
                obj.put("status", -5);
                obj.put("msg", ApiErrorCode.getInstance().getErrorMsg(-5));
                //返回客户
                ParameterTool.writeResponse(response, obj.toString());
                return null;
            }

            String userid = request.getHeader("userid");

            userid = AESTool.decryptString(userid);// 解密userid

            UserT userT = (UserT) redisClientUtils.getObject("userT" + userid);

            if (null == userT) {
                userT = loginDao.getUserByid(userid);
                int redisCacheTime = Integer.valueOf(propertiesUtils.getPropertiesValue("redisCacheTime"));
                redisClientUtils.setObject("userT" + userT.getId(), userT, redisCacheTime);
            }

            String gtId = redisClientUtils.hget(GETUI_KEY, userT.getUserName());
            if (StringUtils.isBlank(gtId)) {
                //判断数据库中是否存在
                String cid = loginDao.getClientId(userT.getUserName());
                if (!StringUtils.isBlank(cid)) {
                    //1. 如果存在，则修改
                    try {
                        loginDao.updRelationShip(userT.getUserName(), (String) map.get("cId"));
                    } catch (Exception e) {
                        log.error(e.getMessage(), e);
                    }
                } else {
                    //2.不存在，则插入
                    try {
                        loginDao.addRelationShip(userT.getUserName(), (String) map.get("cId"));
                    } catch (Exception e) {
                        log.error(e.getMessage(), e);
                    }
                }
            } else {
                // 如果不是空，则需要修改
                try {
                    loginDao.updRelationShip(userT.getUserName(), (String) map.get("cId"));
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                }
            }

            redisClientUtils.hset(GETUI_KEY, userT.getUserName(), (String) map.get("cId"));
            obj.put("status", 0);
            obj.put("msg", "");
            ParameterTool.writeResponse(response, obj.toString());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

        return null;
    }

    @Override
    public ModelAndView unbindClientId(Map<String, Object> map) {
        try {
            HttpServletResponse response = (HttpServletResponse) map.get("response");
            HttpServletRequest request = (HttpServletRequest) map.get("request");
            JSONObject obj = new JSONObject();

            String userid = request.getHeader("userid");

            userid = AESTool.decryptString(userid);// 解密userid

            UserT userT = (UserT) redisClientUtils.getObject("userT" + userid);

            if (null == userT) {
                userT = loginDao.getUserByid(userid);
                int redisCacheTime = Integer.valueOf(propertiesUtils.getPropertiesValue("redisCacheTime"));
                redisClientUtils.setObject("userT" + userT.getId(), userT, redisCacheTime);
            }

            // 数据库删除
            loginDao.delRelationShip(userT.getUserName());

            redisClientUtils.hdel(GETUI_KEY, userT.getUserName());
            obj.put("status", 0);
            obj.put("msg", "");
            ParameterTool.writeResponse(response, obj.toString());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

        return null;
    }

    @Override
    public ModelAndView getClientId(Map<String, Object> map) {
        try {
            HttpServletResponse response = (HttpServletResponse) map.get("response");
            JSONObject obj = new JSONObject();
            if (StringUtils.isEmpty((String) map.get("userName"))) {
                obj.put("status", -5);
                obj.put("msg", ApiErrorCode.getInstance().getErrorMsg(-5));
                //返回客户
                ParameterTool.writeResponse(response, obj.toString());
                return null;
            }
            String cId = redisClientUtils.hget(GETUI_KEY, (String) map.get("userName"));
            if (StringUtils.isBlank(cId)) {
                cId = loginDao.getClientId((String) map.get("userName"));
            }
            obj.put("status", 0);
            obj.put("data", cId);
            obj.put("msg", "");
            ParameterTool.writeResponse(response, obj.toString());
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

        return null;
    }


    @Override
    public void pushUser(Integer function, Integer category, Long orderId, Long receiverId, String userName, String title, String content, String transmissionContent, Long creatorId) {
        // 若接收人ID和接收人用户名均为空，存储异常信息
        if (!NumberUtils.isPositiveNum(receiverId) && StringUtils.isEmpty(userName)) {
            savePushNotifyRecord(orderId, function, category, 2, null, content, 0, "用户信息不存在，无法推送", creatorId);
            return;
        }

        // 如果接收人ID为空，通过用户名获取ID参数
        if (!NumberUtils.isPositiveNum(receiverId)) {
            UserT receiver = loginDao.getUserByUserName(userName);
            if (null != receiver) {
                receiverId = receiver.getId();
            }
        }

        // 如果接收人用户名为空，通过用户ID获取用户名参数
        if (StringUtils.isEmpty(userName)) {
            UserT receiver = loginDao.getUserByid(String.valueOf(receiverId));
            if (null != receiver) {
                userName = receiver.getUserName();
            }
        }

        /**
         * 2.10.0CRM异常关闭取消了用用户的消息推送，但保存消息记录
         */
        // 保存正常发送记录
        savePushNotifyRecordDeleted(orderId, function, category, 2, receiverId, content, 1, null, creatorId);
    }

    /**
     * 保存推送通知记录
     *
     * @param orderId       工单编号
     * @param function      功能
     * @param category      类别
     * @param receiverId    接收人id
     * @param content       推送内容
     * @param status        推送状态
     * @param exceptionInfo 异常信息
     * @param creatorId     创建人id
     */
    private void savePushNotifyRecordDeleted(Long orderId, Integer function, Integer category, Integer sendType, Long receiverId, String content, Integer status, String exceptionInfo, Long creatorId) {
        // 获取系统当前时间
        String currentTime = LocalTimeUtil.getRealCurrentTime();
        NotifyRecord notifyRecord = new NotifyRecord();
        notifyRecord.setOrderId(orderId);
        notifyRecord.setFunction(function);
        notifyRecord.setCategory(category);
        notifyRecord.setReceiverId(receiverId);
        notifyRecord.setContent(content);
        notifyRecord.setSendType(sendType);
        notifyRecord.setSendTime(currentTime);
        notifyRecord.setStatus(status);
        notifyRecord.setExceptionInfo(exceptionInfo);
        notifyRecord.setIsRead(0);
        notifyRecord.setFlag(-1);
        notifyRecord.setCreator(creatorId);
        notifyRecord.setCreateTime(currentTime);
        // 保存发送记录
        notifyRecordTDao.saveNotifyRecord(notifyRecord);
    }


    @Override
    public void push(Integer function, Integer category, Long orderId, Long receiverId, String userName, String title, String content, String transmissionContent, Long creatorId) {
        // 若接收人ID和接收人用户名均为空，存储异常信息
        if (!NumberUtils.isPositiveNum(receiverId) && StringUtils.isEmpty(userName)) {
            savePushNotifyRecord(orderId, function, category, 2, null, content, 0, "用户信息不存在，无法推送", creatorId);
            return;
        }

        // 如果接收人ID为空，通过用户名获取ID参数
        if (!NumberUtils.isPositiveNum(receiverId)) {
            UserT receiver = loginDao.getUserByUserName(userName);
            if (null != receiver) {
                receiverId = receiver.getId();
            }
        }

        // 如果接收人用户名为空，通过用户ID获取用户名参数
        if (StringUtils.isEmpty(userName)) {
            UserT receiver = loginDao.getUserByid(String.valueOf(receiverId));
            if (null != receiver) {
                userName = receiver.getUserName();
            }
        }

        // 获取用户对应的clientId
        // 先通过redis获取
        String clientId = redisClientUtils.hget(RedisKeys.geTuiKey(), userName);
        if (StringUtils.isEmpty(clientId)) {
            // redis中不存在，查询数据库
            RelationShipT relationShipT = relationShipTDao.getClientIdByUserNameString(userName);
            if (null != relationShipT) {
                clientId = relationShipT.getClientId();
            }
        }

        // ClientId不为空时，进行推送操作，为空时进行异常记录
        if (StringUtils.isNotEmpty(clientId)) {
            // 发送推送操作
            NotifyUtil.push2Single(clientId, title, content, 2, transmissionContent);
            // 保存正常发送记录
            savePushNotifyRecord(orderId, function, category, 2, receiverId, content, 1, null, creatorId);
        } else {
            // 保存不存在ClientId的异常记录
            savePushNotifyRecord(orderId, function, category, 2, receiverId, content, 0, "用户ClientId不存在", creatorId);
        }
    }


    @Override
    public void sendSMS(Integer function, Integer category, Long orderId, Long receiverId, String userPhone, String content, Long creatorId) {
        // 若接收人ID和接收人用户名均为空，存储异常信息
        if (!NumberUtils.isPositiveNum(receiverId) && StringUtils.isEmpty(userPhone)) {
            savePushNotifyRecord(orderId, function, category, 1, null, content, 0, "用户信息不存在，无法发送短信", creatorId);
            return;
        }

        // 如果接收人ID为空，通过用户手机号获取ID参数
        if (!NumberUtils.isPositiveNum(receiverId)) {
            UserT receiver = userTDao.getUserByPhone(userPhone);
            if (null != receiver) {
                receiverId = receiver.getId();
            }
        }

        // 如果接收人手机号为空，通过用户ID获取手机号参数
        if (StringUtils.isEmpty(userPhone)) {
            UserT receiver = userTDao.selectById(receiverId);
            if (null != receiver) {
                userPhone = receiver.getPhone();
            }
        }

        // Phone不为空时，进行发送短信操作，为空时进行异常记录
        if (StringUtils.isNotEmpty(userPhone)) {
            // 发送短信操作
            SmsUtils.sendMessage(userPhone, content);
            // 保存正常发送记录
            savePushNotifyRecord(orderId, function, category, 1, receiverId, content, 1, null, creatorId);
        } else {
            // 保存不存在ClientId的异常记录
            savePushNotifyRecord(orderId, function, category, 1, receiverId, content, 0, "用户手机号为空无法发送短信", creatorId);
        }
    }

    @Override
    public ModelAndView openActivity(Map<String, Object> map) {
            String activityType = redisClientUtils.set("Common-VIDEOSUBMISSIONS", MapUtils.getString(map, "activityType"), 0);
            if (activityType.equals("OK")) {
                ParameterTool.writeSuccessResponse((HttpServletResponse) map.get("response"));
                return null;
            }
        return null;
    }


    /**
     * 保存推送通知记录
     *
     * @param orderId       工单编号
     * @param function      功能
     * @param category      类别
     * @param receiverId    接收人id
     * @param content       推送内容
     * @param status        推送状态
     * @param exceptionInfo 异常信息
     * @param creatorId     创建人id
     */
    private void savePushNotifyRecord(Long orderId, Integer function, Integer category, Integer sendType, Long receiverId, String content, Integer status, String exceptionInfo, Long creatorId) {
        // 获取系统当前时间
        String currentTime = LocalTimeUtil.getRealCurrentTime();
        NotifyRecord notifyRecord = new NotifyRecord();
        notifyRecord.setOrderId(orderId);
        notifyRecord.setFunction(function);
        notifyRecord.setCategory(category);
        notifyRecord.setReceiverId(receiverId);
        notifyRecord.setContent(content);
        notifyRecord.setSendType(sendType);
        notifyRecord.setSendTime(currentTime);
        notifyRecord.setStatus(status);
        notifyRecord.setExceptionInfo(exceptionInfo);
        notifyRecord.setIsRead(0);
        notifyRecord.setFlag(0);
        notifyRecord.setCreator(creatorId);
        notifyRecord.setCreateTime(currentTime);
        // 保存发送记录
        notifyRecordTDao.saveNotifyRecord(notifyRecord);
    }


}
